package com.syezon.wifikey.wifi.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.util.Log;

import com.syezon.wifikey.utils.Utils;
import com.syezon.wifikey.utils.WifiUtil;

import java.util.ArrayList;

/**
 * Created by Administrator on 2018/5/16.
 */

public class WiFiConnectReceiver extends BroadcastReceiver {
    private static final String TAG = WiFiConnectReceiver.class.getSimpleName();

    private static ArrayList<ConnectChangeObserver> mConnectChangeObservers = new ArrayList<ConnectChangeObserver>();

    private static BroadcastReceiver mBroadcastReceiver;

    private NetworkInfo.DetailedState state = NetworkInfo.DetailedState.IDLE;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
            try {
                if (intent.hasExtra(WifiManager.EXTRA_NETWORK_INFO)) {
                    NetworkInfo netInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
                    NetworkInfo.DetailedState detailedState = netInfo.getDetailedState();
                    Log.e(TAG, detailedState + "");
                    NetworkInfo networkInfo = null;
                    String connectedSsid = "";
                    switch (detailedState) {
                        case IDLE:
                            state = NetworkInfo.DetailedState.IDLE;
                            Log.e(TAG, "DISCONNECTED");
                            break;
                        case SCANNING:
                            state = NetworkInfo.DetailedState.SCANNING;
                            Log.e(TAG, "DISCONNECTED");
                            break;
                        case DISCONNECTING:
                            state = NetworkInfo.DetailedState.DISCONNECTING;
                            Log.e(TAG, "DISCONNECTED");
                            break;
                        case DISCONNECTED:
                            state = NetworkInfo.DetailedState.DISCONNECTED;
                            Log.e(TAG, "DISCONNECTED");
                            break;
                        case FAILED:
                            state = NetworkInfo.DetailedState.FAILED;
                            Log.e(TAG, "FAILED");
                            break;
                        case BLOCKED:
                            state = NetworkInfo.DetailedState.BLOCKED;
                            Log.e(TAG, "BLOCKED");
                            break;
                        case CONNECTING:
                            state = NetworkInfo.DetailedState.CONNECTING;
                            Log.e(TAG, "CONNECTING");
                            break;
                        case AUTHENTICATING:
                            state = NetworkInfo.DetailedState.AUTHENTICATING;
                            Log.e(TAG, "AUTHENTICATING");
                            break;
                        case OBTAINING_IPADDR:
                            state = NetworkInfo.DetailedState.OBTAINING_IPADDR;
                            Log.e(TAG, "OBTAINING_IPADDR： " + "额外信息：" + netInfo.getExtraInfo());
                            break;
                        case CONNECTED:
                            state = NetworkInfo.DetailedState.CONNECTED;
                            Log.e(TAG, "CONNECTED");
                            networkInfo = getConnectedWifiNetInfo();
                            connectedSsid = WifiUtil.getWifiSSID();
                            break;
                        case SUSPENDED:
                            state = NetworkInfo.DetailedState.SUSPENDED;
                            Log.e(TAG, "SUSPENDED");
                            break;
                        default:
                            state = NetworkInfo.DetailedState.IDLE;
                            Log.e(TAG, "Default");
                            break;
                    }
                    notifyObserver(state, networkInfo, connectedSsid);
                } else {
                    Log.e(TAG, "广播中没有：WifiManager.EXTRA_NETWORK_INFO");
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static BroadcastReceiver getReceiver() {
        if (null == mBroadcastReceiver) {
            synchronized (WiFiConnectReceiver.class) {
                if (null == mBroadcastReceiver) {
                    mBroadcastReceiver = new WiFiConnectReceiver();
                }
            }
        }
        return mBroadcastReceiver;
    }

    public static void registerNetworkStateReceiver(Context mContext) {
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        mContext.getApplicationContext().registerReceiver(getReceiver(), filter);
    }

    public static void unRegisterNetworkStateReceiver(Context mContext) {
        if (mBroadcastReceiver != null) {
            try {
                mContext.getApplicationContext().unregisterReceiver(mBroadcastReceiver);
            } catch (Exception e) {
            }
        }

    }

    public static void registerObserver(ConnectChangeObserver observer) {
        if (mConnectChangeObservers == null) {
            mConnectChangeObservers = new ArrayList<ConnectChangeObserver>();
        }
        mConnectChangeObservers.add(observer);
    }

    public static void removeRegisterObserver(ConnectChangeObserver observer) {
        if (mConnectChangeObservers != null) {
            if (mConnectChangeObservers.contains(observer)) {
                mConnectChangeObservers.remove(observer);
            }
        }
    }

    private void notifyObserver(NetworkInfo.DetailedState state, NetworkInfo networkInfo, String ssid) {
        if (!mConnectChangeObservers.isEmpty()) {
            int size = mConnectChangeObservers.size();
            for (int i = 0; i < size; i++) {
                ConnectChangeObserver observer = mConnectChangeObservers.get(i);
                if (observer != null) {
                    observer.onConnectedChange(state, networkInfo, ssid);
                    if (state == NetworkInfo.DetailedState.CONNECTED) {
                        observer.onConnected(networkInfo, ssid);
                    }
                    if (state == NetworkInfo.DetailedState.DISCONNECTED) {
                        observer.onDisConnected();
                    }
                }
            }
        }
    }


    private NetworkInfo getConnectedWifiNetInfo() {
        //检测API是不是小于21，因为到了API23之后getNetworkInfo(int networkType)方法被弃用
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
            //获得ConnectivityManager对象
            ConnectivityManager connMgr = (ConnectivityManager) Utils.getApp().getSystemService(Context.CONNECTIVITY_SERVICE);

            //获取ConnectivityManager对象对应的NetworkInfo对象
            //获取WIFI连接的信息
            NetworkInfo wifiNetworkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (wifiNetworkInfo != null && wifiNetworkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
                return wifiNetworkInfo;
            }
//API大于23时使用下面的方式进行网络监听
        } else {
            //获得ConnectivityManager对象
            ConnectivityManager connMgr = (ConnectivityManager) Utils.getApp().getSystemService(Context.CONNECTIVITY_SERVICE);
            //获取所有网络连接的信息
            Network[] networks = connMgr.getAllNetworks();
            //通过循环将网络信息逐个取出来
            for (int i = 0; i < networks.length; i++) {
                //获取ConnectivityManager对象对应的NetworkInfo对象
                NetworkInfo networkInfo = connMgr.getNetworkInfo(networks[i]);
                if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI
                        && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED
                ) {
                    return networkInfo;
                }
            }
        }
        return null;
    }
}
